﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Text.RegularExpressions;

namespace DataAccessComponents
{
    /// <summary>
    /// Klasa odzwierciedlająca tabele "Klienci" z bazy danych
    /// </summary>
    public class Klient : INotifyPropertyChanged, IDataErrorInfo
    {
        /// <summary>
        /// Zmienna zawierająca id_klienta
        /// </summary>        
        private int id_klient;
        
        public int Id_klient
        {
            get { return this.id_klient; }
            set { this.id_klient = value; Czy_zmiana = true; NotifyPropertyChanged("Id_klient"); }
        }

        /// <summary>
        /// Zmienna zawierająca date urodzenia klienta
        /// </summary>
        private DateTime data_urodzenia;

        public DateTime Data_urodzenia
        {
            get { return data_urodzenia; }
            set { data_urodzenia = value; Czy_zmiana = true; NotifyPropertyChanged("Data_urodzenia"); }
        }

        /// <summary>
        /// Zmienna zawierająca imie klienta
        /// </summary>
        private string imie;
                
        public string Imie
        {
            get { return this.imie; }
            set { this.imie = value; Czy_zmiana = true; NotifyPropertyChanged("Imie"); }
        }

        /// <summary>
        /// Zmienna zawierająca nazwisko klienta
        /// </summary>
        private string nazwisko;

        public string Nazwisko
        {
            get { return this.nazwisko; }
            set { this.nazwisko = value; Czy_zmiana = true; NotifyPropertyChanged("Nazwisko"); }
        }

        /// <summary>
        /// Zmienna zawierająca plec klienta
        /// </summary>
        private string plec;

        public string Plec
        {
            get { return this.plec; }
            set { this.plec = value; Czy_zmiana = true; NotifyPropertyChanged("Plec"); }
        }

        /// <summary>
        /// Zmienna zawierająca numer dowodu osobistego klienta
        /// </summary>
        private string nr_dowodu;

        public string Nr_dowodu
        {
            get { return this.nr_dowodu; }
            set { this.nr_dowodu = value; Czy_zmiana = true; NotifyPropertyChanged("Nr_dowodu"); }
        }

        /// <summary>
        /// Zmienna zawierająca numer telefonu stacjonarnego klienta
        /// </summary>
        private string tel_stacjonarny;

        public string Tel_stacjonarny
        {
            get { return this.tel_stacjonarny; }
            set { this.tel_stacjonarny = value; Czy_zmiana = true; NotifyPropertyChanged("Tel_stacjonarny"); }
        }

        /// <summary>
        /// Zmienna zawierając numer telefonu komórkowego klienta
        /// </summary>
        private string tel_komorkowy;

        public string Tel_komorkowy
        {
            get { return this.tel_komorkowy; }
            set { this.tel_komorkowy = value; Czy_zmiana = true; NotifyPropertyChanged("Tel_komorkowy"); }
        }

        /// <summary>
        /// Zmienna zawierająca id_adres z tabeli "Adres" przypisany do klienta
        /// </summary>
        private int id_adres;

        public int Id_adres
        {
            get { return this.id_adres; }
            set { this.id_adres = value; Czy_zmiana = true; NotifyPropertyChanged("Id_adres"); }
        }

        /// <summary>
        /// Adres klienta
        /// </summary>
        private Adres adres;

        public Adres Adres
        {
            get { return adres; }
            set { adres = value; Czy_zmiana = true; NotifyPropertyChanged("Adres"); }
        }

        ///// <summary>
        ///// Zmienna zawierająca id_status z tabeli "Status" przypisany do klienta
        ///// </summary>
        //private int id_status;

        //public int Id_status
        //{
        //    get { return this.id_status; }
        //    set { this.id_status = value; Czy_zmiana = true; NotifyPropertyChanged("Id_status"); }
        //}

        ///// <summary>
        ///// Status klienta
        ///// </summary>
        //private Status status;

        //public Status Status
        //{
        //    get { return status; }
        //    set { status = value; Czy_zmiana = true; NotifyPropertyChanged("Status"); }
        //}

        /// <summary>
        /// Zmienna zawierająca informacje o zezwoleniu na wysyłanie SMS-ów reklamowych do klienta
        /// </summary>
        private bool zezwolenieSMS;

        public bool ZezwolenieSMS
        {
            get { return this.zezwolenieSMS; }
            set { this.zezwolenieSMS = value; Czy_zmiana = true; NotifyPropertyChanged("ZezwolenieSMS"); }
        }

        /// <summary>
        /// Zmienna zawierająca informacje o zezwoleniu na wysyłanie EMAIL reklamowych do klienta
        /// </summary>
        private bool zezwolenieEMAIL;

        public bool ZezwolenieEMAIL
        {
            get { return this.zezwolenieEMAIL; }
            set { this.zezwolenieEMAIL = value; Czy_zmiana = true; NotifyPropertyChanged("ZezwolenieEMAIL"); }
        }
        
        /// <summary>
        /// Zmienna zawierająca email klienta
        /// </summary>
        private string email;

        public string Email
        {
            get { return this.email; }
            set { this.email = value; Czy_zmiana = true; NotifyPropertyChanged("Email"); }
        }

        /// <summary>
        /// Pesel klienta
        /// </summary>
        private string pesel;

        public string Pesel
        {
            get { return this.pesel; }
            set { this.pesel = value; Czy_zmiana = true; NotifyPropertyChanged("Pesel"); }
        }

        /// <summary>
        /// Numer paszportu
        /// </summary>
        private string nr_paszportu;

        public string Nr_paszportu
        {
            get { return this.nr_paszportu; }
            set { this.nr_paszportu = value; Czy_zmiana = true;  NotifyPropertyChanged("Nr_paszportu"); }
        }

        /// <summary>
        /// Data wydaniea paszportu
        /// </summary>
        private DateTime wydanie_paszportu;

        public DateTime Wydanie_paszportu
        {
            get { return this.wydanie_paszportu; }
            set { this.wydanie_paszportu = value; Czy_zmiana = true;  NotifyPropertyChanged("Wydanie_paszportu"); }
        }

        /// <summary>
        /// Numer klienta nadrzędnego, klientem podrzednym jest osoba która wyjezdza razem osoba zamawiającą
        /// </summary>
        private int klient_nadrzedny;

        public int Klient_nadrzedny
        {
            get { return this.klient_nadrzedny; }
            set { this.klient_nadrzedny = value; Czy_zmiana = true; NotifyPropertyChanged("Klient_nadrzedny"); }
        }

        public bool Czy_zmiana { get; set; }

        /// <summary>
        /// Zmienna potrzebna do oznaczenia obiektu
        /// </summary>
        private bool zaznaczony;

        public bool Zaznaczony
        {
            get { return zaznaczony; }
            set { zaznaczony = value; NotifyPropertyChanged("Zaznaczony"); }
        }

        /// <summary>
        /// Konstruktor klasy Klient
        /// </summary>
        /// <param name="idklient">Id klienta w bazie danych</param>
        /// <param name="imie">Imie</param>
        /// <param name="nazwisko">Naziwsko</param>
        /// <param name="plec">Płeć</param>
        /// <param name="nr_dowodu">Nr dowodu osobistego</param>
        /// <param name="tel_stacjonarny">Nr telefonu stacjonarnego</param>
        /// <param name="tel_komorkowy">Nr telefonu komorkowego</param>
        /// <param name="id_adres">Id adresu klienta z tabeli "Adres"</param>
        /// <param name="adr">Adres</param>
        
        /// <param name="zezwolenieSMS">Zezowolenie na wysyłanie wiadomości SMS</param>
        /// <param name="zezwolenieEMAIL">Zezwolenie na wysyłanie wiadomości EMAIL</param>
        /// <param name="email">Adres email klienta</param>
        /// <param name="data_urodzenia">Data urodzenia klienta</param>
        /// <param name="pesel">Nr PESEL</param>
        /// <param name="nr_paszportu">Nr paszportu klienta</param>
        /// <param name="wydanie_paszportu">Data wydania paszportu klienta</param>
        /// <param name="klient_nad">Nr klienta nadrzednego</param>



        public Klient(int idklient, string imie, string nazwisko, string plec, string nr_dowodu,
            string tel_stacjonarny, string tel_komorkowy, int id_adres,Adres adr, bool zezwolenieSMS, bool zezwolenieEMAIL, string email,DateTime data_urodzenia,string pesel,string nr_paszportu,DateTime wydanie_paszportu,int klient_nad)
        {
            this.id_klient = idklient;
            this.imie = imie;
            this.nazwisko = nazwisko;
            this.plec = plec;
            this.nr_dowodu = nr_dowodu;
            this.tel_stacjonarny = tel_stacjonarny;
            this.tel_komorkowy = tel_komorkowy;
            this.id_adres = id_adres;
            
            this.zezwolenieSMS = zezwolenieSMS;
            this.zezwolenieEMAIL = zezwolenieEMAIL;
            this.email = email;
            this.data_urodzenia = data_urodzenia;
            this.pesel = pesel;
            this.nr_paszportu = nr_paszportu;
            this.wydanie_paszportu = wydanie_paszportu;
            this.klient_nadrzedny = klient_nad;
            this.adres = adr;
            

        }

        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            if (this.GetType() != obj.GetType()) return false;

            Klient innyObj = (Klient)obj;

           // if (!id_klient.Equals(innyObj.id_klient)) return false;
            if (!imie.Equals(innyObj.imie)) return false;
            if (!nazwisko.Equals(innyObj.nazwisko)) return false;            
            if (!plec.Equals(innyObj.plec)) return false;
           // if (!nr_dowodu.Equals(innyObj.nr_dowodu)) return false;
            if (!data_urodzenia.Equals(innyObj.data_urodzenia)) return false;
          //  if (!pesel.Equals(innyObj.pesel)) return false;

            return true;

        }

        public override int GetHashCode()
        {
            return this.id_klient.GetHashCode();
        }

        /// <summary>
        /// Konstruktor domyślny klasy Klient
        /// </summary>
        public Klient()
            : this(0, "", "", "", "", "", "", 0,new Adres(),false, false, "",new DateTime(1900,1,1),"","",new DateTime(1900,1,1),0)
        { }



        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }



        public string Error
        {
            get { return string.Empty; }
        }

        public string this[string propertyName]
        {
            get
            {
                string result = string.Empty;
                propertyName = propertyName ?? string.Empty;
                if (propertyName == "Imie")
                {
                    if (string.IsNullOrEmpty(this.Imie))
                    {
                        result = "Pole \"Imie\" nie może być puste";
                    }
                    else if (Regex.IsMatch(this.Imie, @"[@£_^{}\[~\]|ÆæßÉ!¤%&'()\*\+,-.:;<=>§¿]+"))
                    {
                        result = "Pole \"Imie\" zawiera niedozwolone znaki";
                    }
                    else if (this.Imie.Length < 2)
                    {
                        result = "\"Imie\" jest zakrótkie";
                    }
                }
                else if (propertyName == "Nazwisko")
                {
                    if (string.IsNullOrEmpty(this.Nazwisko))
                    {
                        result = "Pole \"Nazwisko\" nie może być puste";
                    }
                    else if (Regex.IsMatch(this.Nazwisko, @"[@£_^{}\[~\]|ÆæßÉ!¤%&'()\*\+,-.:;<=>§?]+"))
                    {
                        result = "Pole \"Nazwisko\" zawiera niedozwolone znaki";
                    }
                    else if (this.Nazwisko.Length < 2)
                    {
                        result = "\"Nazwisko\" jest zakrótkie";
                    }
                }
                else
                    if (propertyName == "Nr_dowodu")
                    {
                        if (string.IsNullOrEmpty(this.Nr_dowodu))
                        {
                            result = "Pole \"Nr_dowodu\" nie może być puste";
                        }
                        else if (Regex.IsMatch(this.Nr_dowodu, @"[@£_^{}\[~\]|ÆæßÉ!¤%&'()\*\+,-.:;<=>§?]+"))
                        {
                            result = "Pole \"Nr_dowodu\" zawiera niedozwolone znaki";
                        }
                        else if (this.Nr_dowodu.Length < 9)
                        {
                            result = "\"Nr_dowodu\" jest zakrótki";
                        }
                        else if (sprNrDowodu(this.Nr_dowodu))
                        {
                            result = "Pole \"Nr_dowodu\" zawiera niepoprawny numer dowodu";
                        }
                    }
                    else
                        if (propertyName == "Tel_stacjonarny")
                        {
                            if (string.IsNullOrEmpty(this.Tel_stacjonarny))
                            {
                                result = "Pole \"Tel_stacjonarny\" nie może być puste";
                            }
                            else if (!Regex.IsMatch(this.Tel_stacjonarny, "[0-9]{9}"))
                            {
                                result = "Pole \"Tel_stacjonarny\" zawiera niedozwolone znaki";
                            }
                            else if (this.Tel_stacjonarny.Length < 9)
                            {
                                result = "\"Tel_stacjonarny\" jest zakrótkie";
                            }
                            else if (this.Tel_stacjonarny.Length > 9)
                            {
                                result = "\"Tel_stacjonarny\" jest zadługie";
                            }
                        }
                        else
                            if (propertyName == "Tel_komorkowy")
                            {
                                if (string.IsNullOrEmpty(this.Tel_komorkowy))
                                {
                                    result = "Pole \"Tel_komorkowy\" nie może być puste";
                                }
                                else if (!Regex.IsMatch(this.Tel_komorkowy, "[0-9]{9}"))
                                {
                                    result = "Pole \"Tel_komorkowy\" zawiera niedozwolone znaki";
                                }
                                else if (this.Tel_komorkowy.Length < 9)
                                {
                                    result = "\"Tel_komorkowy\" jest zakrótkie";
                                }
                                else if (this.Tel_komorkowy.Length > 9)
                                {
                                    result = "\"Tel_komorkowy\" jest zadługie";
                                }
                            }
                            else if (propertyName == "Email")
                            {
                                if (string.IsNullOrEmpty(this.Email))
                                {
                                    result = "Pole \"Email\" nie może być puste";
                                }
                                else if (!Regex.IsMatch(this.Email, @"^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.([a-zA-Z]{2,}){1}$"))
                                {
                                    result = "Pole \"Email\" zawiera nie poprawny adres email";
                                }
                            }
                            else if (propertyName == "Data_urodzenia")
                            {
                                if (this.Data_urodzenia.ToShortDateString().Contains('-'))
                                {
                                    string[] data = this.Data_urodzenia.ToShortDateString().Split('-');
                                    if (data.Length == 3)
                                    {
                                        string dataFormat = string.Format("{2}/{1}/{0}", data[0], data[1], data[2]);
                                        DateTime dt = new DateTime();
                                        if (!DateTime.TryParse(dataFormat, out dt))
                                        {
                                            result = "Niepoprawna data (dd-mm-rrrr)";
                                        }                                        
                                        
                                    }
                                    else
                                    {
                                        result = "Niepoprawna format daty (dd-mm-rrrr)";
                                    }

                                }
                                else if (!this.Data_urodzenia.ToShortDateString().Contains('-'))
                                {
                                    result = "Niepoprawna format daty (dd-mm-rrrr)";
                                }
                            }
                            else if (propertyName == "Pesel")
                            {
                                if (string.IsNullOrEmpty(this.Pesel))
                                {
                                    result = "Pole \"Pesel\" nie może być puste";
                                }
                                else if (!Regex.IsMatch(this.Pesel, @"^[0-9]{11}$"))
                                {
                                    result = "Pole \"Pesel\" zawiera niedozwolone znaki";
                                }
                                else if (this.Pesel.Length < 11)
                                {
                                    result = "\"Pesel\" jest zakrótki";
                                }
                                else if (!sprPesel(this.Pesel))
                                {
                                    result = "Pole \"Pesel\" zawiera numer PESEL";
                                }
                            }
                            else if (propertyName == "Nr_paszportu")
                            {
                                if (string.IsNullOrEmpty(this.Nr_paszportu))
                                {
                                    result = "Pole \"Nr_paszportu\" nie może być puste";
                                }
                                else if (Regex.IsMatch(this.Nr_paszportu, @"[@£_^{}\[~\]|ÆæßÉ!¤%&'()\*\+,-.:;<=>§?]+"))
                                {
                                    result = "Pole \"Nr_paszportu\" zawiera niedozwolone znaki";
                                }
                                else if (this.Nr_paszportu.Length < 9)
                                {
                                    result = "\"Nr_paszportu\" jest zakrótkie";
                                }
                                else if (sprNrDowodu(this.Nr_paszportu))
                                {
                                    result = "Pole \"Nr_paszportu\" zawiera niepoprawny numer paszportu";
                                }
                            }
                            else if (propertyName == "Wydanie_paszportu")
                            {
                                if (this.Wydanie_paszportu.ToString().Contains('-'))
                                {
                                    string[] data = this.Wydanie_paszportu.ToShortDateString().Split('-');
                                    if (data.Length == 3)
                                    {
                                        string dataFormat = string.Format("{2}/{1}/{0}", data[0], data[1], data[2]);
                                        DateTime dt = new DateTime();
                                        if (!DateTime.TryParse(dataFormat, out dt))
                                            result = "Niepoprawna data (dd-mm-rrrr)";
                                    }
                                    else
                                    {
                                        result = "Niepoprawna format daty (dd-mm-rrrr)";
                                    }

                                }
                                else if (!this.Wydanie_paszportu.ToShortDateString().Contains('-'))
                                {
                                    result = "Niepoprawna format daty (dd-mm-rrrr)";
                                }
                            }
                            


                return result;
            }
        }
        private bool sprPesel(string numer)
        {
            char[] znaki = numer.ToCharArray();
            if (znaki.Length == 11)
            {
                int[] wagi = { 1, 3, 7, 9, 1, 3, 7, 9, 1, 3 };
                int suma = 0;

                for (int i = 0; i < znaki.Length - 1; i++)
                {
                    suma += Int32.Parse(znaki[i].ToString()) * wagi[i];
                }
                int reszta = suma % 10;
                int cyfraKontrolna = Int32.Parse(znaki.Last().ToString());
                if (reszta == 0 && reszta == cyfraKontrolna)
                {
                    return true;
                }
                else if (reszta != 0 && (10 - reszta) == cyfraKontrolna)
                {
                    return true;
                }
                else
                    return false;
            }
            else
                return false;
        }
        private bool sprNrDowodu(string numer)
        {

            int[] wagi = { 7, 3, 1, 9, 7, 3, 1, 7, 3 };
            char[] znaki = numer.ToCharArray();
            if (znaki.Length == 9)
            {
                int sumowanie = 0;
                for (int i = 0; i < znaki.Length; i++)
                {
                    if (znaki[i] >= 65 && znaki[i] <= 90)
                        sumowanie += (int)znaki[i] - 55 * wagi[i];
                    else
                        sumowanie += (int)znaki[i] - 48 * wagi[i];
                }
                // Jezeli reszta z dzielenia przez 10 wynosi 0 to true
                if (sumowanie % 10 == 0)
                {
                    return true;
                }
                else
                    return false;
            }
            else
                return false;
        }
        private bool sprNrPaszportu(string numer)
        {

            int[] wagi = { 7, 3, 9, 1, 7, 3, 1, 7, 3 };
            char[] znaki = numer.ToCharArray();
            if (znaki.Length == 9)
            {
                int sumowanie = 0;
                for (int i = 0; i < znaki.Length; i++)
                {
                    if (znaki[i] >= 65 && znaki[i] <= 90)
                        sumowanie += (int)znaki[i] - 55 * wagi[i];
                    else
                        sumowanie += (int)znaki[i] - 48 * wagi[i];
                }
                // Jezeli reszta z dzielenia przez 10 wynosi 0 to true
                if (sumowanie % 10 == 0)
                {
                    return true;
                }
                else
                    return false;
            }
            else
                return false;
        }

    }
}
